package com.qf.realm;

import com.qf.entity.Menu;
import com.qf.entity.Role;
import com.qf.entity.User;
import com.qf.mapper.UserMapper;
import com.qf.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;


public class CustomRealm extends AuthorizingRealm {


    @Autowired
    private UserService userService;

    // 设置MD5加密1024次.
    {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");
        matcher.setHashIterations(1024);
        this.setCredentialsMatcher(matcher);
    }



    @Override
    // 认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1. 获取用户输入的用户名.
        String username = (String) token.getPrincipal();
        //2. 根据用户名查询用户信息. (userService) (模拟数据库操作)
        User user = userService.findByUsername(username);
        //3. 判断用户信息是否为null -> 直接返回true
        if(user == null){
            return null;
        }
        if(user.getStatus()!=0){
            throw new DisabledAccountException();
        }
        //4. 将正确的user对象和密码封装到AuthenticationInfo对象中.
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),"嘿嘿嘿.");
        //5. 将盐设置到info对象中
        info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
        //6. 返回AuthenticationInfo对象.0
        return info;
    }




    @Override
    // 授权.
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//        1. 获取当前登录用户的用户名.
        User user = (User) principals.getPrimaryPrincipal();
//        String username = user.getUsername();
//        2. 根据用户名查询全部的角色.
        Role role = userService.findRole(user.getUserId());
//        3. 根据当前角色查询菜单.
        List<Menu> menus = role.getMenus();
//        4. 创建返回结果info.
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //封装角色
        info.addRole(role.getRoleName());
        ArrayList permissionList = new ArrayList();
        //遍历一级菜单
        for (Menu menu : menus) {
            //遍历二级菜单的请求
            for (Menu men : menu.getMenus()) {
                permissionList.add(men.getPreCode());
            }
        }
        //封装请求
        info.addStringPermissions(permissionList);
//        5. 返回.
        return info;
    }

}
